#include<iostream>
#include<signal.h>
#include<cassert>
#include<unistd.h>

using namespace std;

static void PrintPending(const sigset_t pending)
{
    cout <<"当前进程的pending位图：";
    for(int signo = 1; signo <= 31;signo++)
    {
        if(sigismember(&pending,signo)) cout <<"1";
        else cout <<"0";
    }
    cout << "\n";
}

static void handler(int signo)
{
    cout << "对特定信号" << signo << "执行捕捉动作" << endl;
}
int main()
{
    //1.屏蔽2号信号
    sigset_t set,oset;
    //1.1初始化set所指向的信号集
    sigemptyset(&set);
    sigemptyset(&oset);

    //1.2将2号信号添加到set集合中
    sigaddset(&set,2);

    //1.3将新的信号屏蔽字，设置到进程当中
    sigprocmask(SIG_BLOCK, &set, &oset);

    //2.while获取进程的pending信号集，并以01打印
    //2.0 设置对2号信号的自定义捕捉
    signal(2,handler);
    int cnt = 0;
    while(true)
    {
        //到这个地方为止，虽然2号信号被屏蔽了，但是还并未产生信号，所以pending位图还是全0
        
        //2.1先获取pending信号集
        sigset_t pending;
        //初始化pending信号集
        sigemptyset(&pending);//不是必需的

        int n = sigpending(&pending);
        assert(n == 0);
        (void)n;//保证不会出现编译时的warning，需要定义并使用，不然有些编译器可能会报错
        
        //2.2打印所有的pending信号集
        PrintPending(pending);
        sleep(1);

        //2.3休眠一下
        sleep(1);

        //2.4 10s之后，解除对2号信号的屏蔽
        if(cnt++ == 10)
        {
            cout << "解除对2号信号的屏蔽" << endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);
        }
    }
}
